package com.edoomath.api.servcice.impl;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.persistence.annotation.Dao;
import com.demo2do.core.utils.JsonUtils;
import com.edoomath.api.dao.CourseDao;
import com.edoomath.api.dao.SkuDao;
import com.edoomath.api.dao.UserDao;
import com.edoomath.api.entity.Recharge;
import com.edoomath.api.handler.PaymentHandler;
import com.edoomath.api.servcice.RechargeOrderService;
import com.edoomath.entity.course.Course;
import com.edoomath.entity.course.Sku;
import com.edoomath.entity.recharge.RechargeOrder;
import com.edoomath.entity.trade.PaymentRequest;
import com.edoomath.entity.user.User;
import com.edoomath.entity.user.UserSource;
import com.edoomath.entity.user.WechatOpenid;

/**
 * 
 * @author mohanlan
 *
 */
@Service("rechargeOrderService")
public class RechargeOrderServiceImpl implements RechargeOrderService {
	
	private static final Logger logger = LoggerFactory.getLogger(RechargeOrderServiceImpl.class);
	
	@Autowired
	private GenericDaoSupport genericDaoSupport;
	
	@Dao
	private SkuDao skuDao;
	
	@Dao
	private CourseDao courseDao;
	
	@Dao
	private UserDao userDao;
	
	
	@Autowired
    private PaymentHandler      paymentHandler;
	
	/*
	 * (non-Javadoc)
	 * @see com.edoomath.api.servcice.RechargeOrderService#load(java.lang.Long)
	 */
	public RechargeOrder load(Long orderId) {
		return genericDaoSupport.searchForObject("FROM RechargeOrder WHERE id = :id", "id", orderId, RechargeOrder.class);
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.edoomath.api.servcice.RechargeOrderService#createOrder(com.edoomath.api.entity.Recharge, com.edoomath.entity.user.User)
	 */
	public RechargeOrder createOrder(Recharge recharge, User user) {
		
		
		logger.info("price is [{}]", recharge.getPrice());
		
        // 1. bind user's mobile
        if ( StringUtils.isNotBlank(recharge.getMobile()) ) {
            genericDaoSupport.update(user.editMobile(recharge.getMobile()));
        }
        
        Sku sku = null;
        Course course = null;
        if(recharge.getSkuId() != null) {
        	sku = skuDao.load(recharge.getSkuId());
        	course = courseDao.loadCourse(sku);
        }
		
        RechargeOrder rechargeOrder = new RechargeOrder(user, recharge.getMobile(), recharge.getPrice(), sku, course);
        genericDaoSupport.save(rechargeOrder);
        
		return rechargeOrder;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.edoomath.api.servcice.RechargeOrderService#prepay(com.edoomath.entity.recharge.RechargeOrder, com.edoomath.entity.user.User, java.lang.String)
	 */
	public Map<String, Object> prepay(RechargeOrder rechargeOrder, User user, String remoteIp) {
		
		try {
			
			WechatOpenid wechatOpenid = userDao.loadOpenid(user.getUnionid(), UserSource.EDOOMATH_WEAPP_ACCOUNT);
            
            // 1. create payment request
            PaymentRequest paymentRequest = new PaymentRequest(rechargeOrder.getCode(), null);
            genericDaoSupport.save(paymentRequest.initliaze());
            
            logger.trace("#prepay() - Get remote IP address [{}].", remoteIp);
            Map<String, Object> parameters = new HashMap<String, Object>();
            parameters.put("order_no", paymentRequest.getOrderCode());
            parameters.put("request_no", paymentRequest.getCode());
            parameters.put("user_id", wechatOpenid.getOpenid());
            parameters.put("channel", "weapppay");
            parameters.put("amount", rechargeOrder.getPrice());
            parameters.put("subject", "陆老师小打卡课时充值");  // FIXME
            
            // 2. generate wechat pay context
            Map<String, Object> wechatPayContext = paymentHandler.generateWechatPayContext(parameters);
            logger.trace("#prepay() - Get wechatPayContext here [{}]", JsonUtils.toJson(wechatPayContext));
            
            return wechatPayContext;

		
		} catch (Exception e) {
            logger.error("#prepay - occurs error", e);
            throw BusinessException.newInstance("500", "充值支付失败");
        }
	}
	
}
